#!/usr/bin/env python

################################################################################
# Python Standard Library
################################################################################

################################################################################
# Includes
################################################################################

from protocols.d2 import D2Packet, D2Socket
from protocols.game import GamePacket, GameSocket
from protocols.client import ClientPacket, ClientSocket

################################################################################
# Packets
################################################################################

WalkToLocation							= "\x01"
WalkToTarget							= "\x02"
RunToLocation							= "\x03"
RunToTarget 							= "\x04"
CastLeftSkill 							= "\x05"
CastLeftSkillOnTarget 					= "\x06"
CastLeftSkillOnTargetStopped 			= "\x07"
RecastLeftSkill 						= "\x08"
RecastLeftSkillOnTarget 				= "\x09"
RecastLeftSkillOnTargetStopped 			= "\x0A"
CastRightSkill 							= "\x0C"
CastRightSkillOnTarget 					= "\x0D"
CastRightSkillOnTargetStopped 			= "\x0E"
RecastRightSkill 						= "\xF0"
RecastRightSkillOnTarget 				= "\x10"
RecastRightSkillOnTargetStopped 		= "\x11"
UnitInteract 							= "\x13"
SendOverheadMessage 					= "\x14"
SendMessage 							= "\x15"
PickItem 								= "\x16"
DropItem 								= "\x17"
DropItemToContainer 					= "\x18"
PickItemFromContainer 					= "\x19"
EquipItem 								= "\x1a"
UnequipItem 							= "\x1c"
SwapEquippedItem 						= "\x1d"
SwapContainerItem 						= "\x1f"
UseInventoryItem 						= "\x20"
StackItems 								= "\x21"
AddBeltItem 							= "\x23"
RemoveBeltItem							= "\x24"
SwapBeltItem							= "\x25"
UseBeltItem								= "\x26"
IdentifyItem							= "\x27"
EmbedItem								= "\x29"
ItemToCube								= "\x2a"
TownFolkInteract						= "\x2f"
TownFolkCancelInteraction				= "\x30"
DisplayQuestMessage						= "\x31"
BuyItem									= "\x32"
SellItem								= "\x33"
CainIdentifyItems						= "\x34"
TownFolkRepair							= "\x35"
HireMercenary							= "\x36"
IdentifyGambleItem						= "\x37"
TownFolkMenuSelect						= "\x38"
IncrementAttribute						= "\x3a"
IncrementSkill							= "\x3b"
SelectSkill								= "\x3C"
HoverUnit								= "\x3d"
SendCharacterSpeech						= "\x3f"
RequestQuestLog							= "\x40"
Respawn									= "\x41"
WaypointInteract						= "\x49"
RequestReassign							= "\x4b"
ClickButton								= "\x4f"
DropGold								= "\x50"
SetSkillHotkey							= "\x51"
CloseQuest								= "\x58"
GoToTownFolk							= "\x59"
SetPlayerRelation						= "\x5d"
PartyRequest							= "\x5e"
UpdatePosition							= "\x5f"
SwitchWeapons							= "\x60"
ChangeMercEquipment						= "\x61"
ResurrectMerc							= "\x62"
InventoryItemToBelt						= "\x63"
WardenResponse							= "\x66"
GameLogonRequest						= "\x68"
ExitGame								= "\x69"
EnterGame								= "\x6b"
Ping									= "\x6d"

Invalid									= "\x6E"

Wrapper									= "\xF00"
GoToLocation							= "\xF01"
GoToTarget								= "\xF02"

################################################################################
# Packet Handlers
################################################################################

class D2GCPacket(D2Packet, GamePacket, ClientPacket):
	"""
	Diablo II Game Client Packet
	"""
	
	def __init__(self):
		D2Packet.__init__(self)
		GamePacket.__init__(self)
		ClientPacket.__init__(self)
	
	def unpack(self):
		print "Unpacking D2GC packet..."
		
		self.dispatchEvent("unpack", (self,))
		
		print "D2GC packet unpacked."
	
	def pack(self):
		print "Packing D2GC packet..."
		
		self.dispatchEvent("pack", (self,))
		
		print "D2GC packet packed."
		
		return self.message

	def decompress(self):
		pass
	
	def compress(self):
		pass

################################################################################
# Socket Handlers
################################################################################

class D2GCSocket(D2Socket, GameSocket, ClientSocket):
	"""
	Diablo II Game Client Socket
	"""
	
	def __init__(self, sock = None):
		D2Socket.__init__(self, sock)
		GameSocket.__init__(self, sock)
		ClientSocket.__init__(self, sock)
		
		self.compressed = False
	
	def unpackPackets(self):
		i, l = 0, len(self.data)
		
		while i < l:
			if self.compressed:
				packet = D2GCPacket()
				packet.socket = self
				packet.messageSize = int(self.data[i])
				packet.messageID = self.data[i+1] #decompress this
				packet.messageLength = len(self.data)
				packet.messageData = self.data[i+1:packet.messageLength-1]
				packet.message = self.data[i:i+packet.messageLength]
			else:
				packet = D2GCPacket()
				packet.socket = self
				packet.messageID = self.data[i]
				packet.messageLength = len(self.data)
				packet.messageData = self.data[i:packet.messageLength]
				packet.message = self.data[i:i+packet.messageLength]
			
			packet.unpack()
			
			self.packets.append(packet)
			
			i += packet.messageLength
		
		self.data = ''